package cn.com.nes.site.interceptor;

import cn.com.nes.common.util.JsonUtil;
import cn.com.nes.common.util.JwtUtil;
import cn.com.nes.site.entity.PageData;
import cn.com.nes.site.entity.UserInfo;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * 权限验证拦截器
 *  目前项目中有两种接口编写方式， 该拦截器只对 ‘/v2’ 开始的请求拦截，进行权限验证
 */
@Slf4j
@Component
public class AuthInterceptor extends HandlerInterceptorAdapter {

    public AuthInterceptor() {
        log.debug("AuthInterceptor Construct");
    }

    private List<String> allowUrls;

    public List<String> getAllowUrls() {
        return allowUrls;
    }

    public void setAllowUrls(List<String> allowUrls) {
        this.allowUrls = allowUrls;
    }

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object o) throws Exception {
        // log.info("===== 前置处理");
        // 获取请求名称
        String servletPath = req.getServletPath();
        if (isAllowUrl(servletPath)) {
            log.info("===== 放行请求:{}", servletPath);
            return true;
        }

        String key = req.getHeader("key");
        if (ObjectUtil.isEmpty(key)) {
            key = req.getHeader("token");
        }
        if (ObjectUtil.isNull(key)) {
            return errorResult("没有权限", res);
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest req, HttpServletResponse res, Object o,
            ModelAndView modelAndView) throws Exception {
        // log.info("postHandle");
        // log.info("===== 后置处理");
    }

    @Override
    public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object o,
            Exception e) throws Exception {
    }

    /**
     * 解析token，获取用户信息
     * @param key
     * @return
     */
    private UserInfo getKey(String key) throws Exception {
        JwtUtil util = new JwtUtil();
        Claims c = util.parseJWT(key);// 注意：如果jwt已经过期了，这里会抛出jwt过期异常。
        String json = c.getSubject();
        UserInfo uinfo = (UserInfo) JsonUtil.getObjFromStr(json, UserInfo.class);
        return uinfo;
    }

    /**
     * 校验失败返回数据，使用方法。
     * @param resultMsg 提示用户的msg
     * @param res       {@link HttpServletResponse}
     * @return false: 验证失败
     */
    private boolean errorResult(String resultMsg, HttpServletResponse res) throws IOException {
        PageData result = PageData.error(resultMsg);
        String json = JSONObject.toJSONString(result);
        res.setContentType("application/json;charset=UTF-8");
        res.getWriter().print(json);
        return false;
    }

    private boolean isAllowUrl(String requestUrl) {
        if (CollUtil.isNotEmpty(allowUrls)) {
            for (String url : allowUrls) {
                if (requestUrl.endsWith(url)) {
                    return true;
                }
            }
        }
        return false;
    }
}
